package cn.codergege.demo.config

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
import org.springframework.context.annotation.Profile
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.orm.jpa.JpaTransactionManager
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
import org.springframework.orm.jpa.vendor.Database
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.annotation.EnableTransactionManagement
import javax.persistence.EntityManager
import javax.sql.DataSource
import org.springframework.jdbc.core.JdbcTemplate

/**
 *  可以配置的地方:
 *      1. @EnableJpaRepositories: basePackages // repository 所在包
 *      2. getVendorProperties:
 *          1) jpaProperties.database = Database.MYSQL // 设置数据库类型
 *          2) jpaProperties.isShowSql = false // 是否显示 sql
 *          3) ddlAuto { "update" } // dll-auto 生成环境最好设置为 none
 *          4) physicalNamingStrategy(SpringPhysicalNamingStrategy()) // 命名策略
 *      3. emfPrimary: packages("cn.codergege.demo.entity.primary") // 实体类所在包
 */
@Profile("dev", "prod")
@EnableJpaRepositories(
    basePackages = arrayOf("cn.codergege.demo.dao.secondary"), // repository 所在包
    entityManagerFactoryRef = "emfSecondary",
    transactionManagerRef = "txmSecondary"
)
@EnableTransactionManagement
@Configuration
class SecondaryConfig {

    @Autowired
    @Qualifier("dataSourceSecondary")
    lateinit var dataSourceSecondary: DataSource

    /**
     *  注入 jpa 配置实体
     */
    @Autowired
    lateinit var jpaProperties: JpaProperties

    /**
     *  设置 jpaProperties
     */
    private fun getVendorProperties(): Map<String, Any> {
        // 设置数据库类型
        jpaProperties.database = Database.MYSQL
        // 是否显示 sql
        jpaProperties.isShowSql = false

        return jpaProperties.getHibernateProperties(
            HibernateSettings()
                .ddlAuto {
                    "update"
                }
                .physicalNamingStrategy(SpringPhysicalNamingStrategy())
        )
    }

    @Bean
    fun jdbcTemplateSecondary(): JdbcTemplate {
        return JdbcTemplate(dataSourceSecondary)
    }

    // 设置实体类所在包
    @Bean
    fun emfSecondary(builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
        return builder
            .dataSource(dataSourceSecondary)
            .packages("cn.codergege.demo.entity.secondary")
            // primaryPersistenceUnit
            .persistenceUnit("persistenceUnitSecondary")
            .properties(getVendorProperties())
            .build()
    }

    /**
     *  enityManagerSecondary
     */
    @Bean
    fun entityManagerSecondary(builder: EntityManagerFactoryBuilder): EntityManager? {
        return emfSecondary(builder).`object`?.createEntityManager()
    }

    /**
     *  txmPrimary
     */
    @Bean
    fun txmSecondary(builder: EntityManagerFactoryBuilder): PlatformTransactionManager {
        return JpaTransactionManager(emfSecondary(builder).`object`!!)
    }

}